Skip to content

feat(core): use shared JS box image for project containers#281

Merged
skulidropek merged 22 commits into
ProverCoderAI:mainfrom
konard:issue-267-99a3d92349cd
May 14, 2026
Merged

feat(core): use shared JS box image for project containers#281
skulidropek merged 22 commits into
ProverCoderAI:mainfrom
konard:issue-267-99a3d92349cd

Conversation

@konard
Copy link
Copy Markdown
Contributor

@konard konard commented May 12, 2026

Summary

Fixes #267.

Switches generated project workspace Dockerfiles from a raw ubuntu:24.04 base to the shared konard/box-js:latest Docker Hub image published by https://github.com/link-foundation/box. The docker-git bootstrap layers, SSH entrypoint, auth bridge, host-Docker-backed runtime contract, and clone/cache orchestration remain owned by docker-git.

Reproduction

Before this change, renderDockerfile(makeTemplateConfig()) emitted:

FROM ubuntu:24.04

and only knew how to rename an existing ubuntu user. That did not satisfy issue #267's requirement to reuse the shared box infrastructure, and it risked duplicate UID-1000 users when a box base already has /home/box.

CI then exposed box-specific follow-up invariants:

  • Non-interactive bash -lc commands sourced /etc/profile.d/zz-prompt.sh, and the prompt script touched /dev/tty without a controlling TTY.
  • konard/box-js inherits HOME=/home/box, WORKDIR=/home/box, and login rc files with absolute /home/box references. After renaming box -> dev, docker exec -u dev bash -lc '...' could still resolve user paths through /home/box, and login shells failed on /home/box/.deno/env.
  • The shared git mirror refresh used +refs/*:refs/*; on public GitHub repositories this enumerated refs/pull/* and timed out the login-context E2E after the cache volume was reused by the PR case.

Changes

  • Add ARG DOCKER_GIT_BASE_IMAGE=konard/box-js:latest and FROM ${DOCKER_GIT_BASE_IMAGE} to generated project Dockerfiles.
  • Keep USER root before docker-git's apt/tool/bootstrap layers so the existing setup remains valid on top of the box image.
  • Rename either box or ubuntu base users to the configured sshUser before falling back to user creation.
  • Normalize inherited image environment after user migration with HOME=/home/<sshUser>, a user-correct PATH, and WORKDIR /home/<sshUser>.
  • Rewrite moved login rc files (.profile, .bashrc, .zshrc, etc.) from /home/box or /home/ubuntu to /home/<sshUser>.
  • Keep /etc/profile.d/bun.sh runtime-relative by writing \$PATH instead of baking the base image build-time PATH.
  • Keep zz-prompt.sh inert for non-interactive shells; interactive shells still install prompt/TTY recovery hooks.
  • Restrict shared mirror refreshes to refs/heads/* and refs/tags/*, so clone-cache reuse does not fetch every GitHub pull-request ref.
  • Mirror renderer changes into packages/app/src/lib for the bundled CLI build.
  • Add regression coverage for the shared base image, base-user migration behavior, HOME/WORKDIR normalization, login rc rewriting, runtime PATH rendering, non-interactive prompt sourcing, and clone-cache ref filtering.
  • Use the Docker Hub JS box because CI confirmed ghcr.io/link-foundation/box:latest currently fails anonymous pulls with HTTP 401, while Docker Hub is publicly pullable. Registry metadata also shows the full konard/box:latest amd64 manifest is about 5.6 GiB compressed, while konard/box-js:latest is about 1.6 GiB compressed and still comes from the same shared box infrastructure.

Mathematical Guarantees

Invariants

  • forall config in TemplateConfig: baseImage(renderDockerfile(config)) = ${DOCKER_GIT_BASE_IMAGE}.
  • forall config in TemplateConfig: sshUser(config) owns /home/sshUser(config) after the user-normalization block when the base image has box, ubuntu, or neither.
  • forall config in TemplateConfig: HOME(renderDockerfile(config)) = /home/sshUser(config) and WORKDIR(renderDockerfile(config)) = /home/sshUser(config).
  • forall p in loginRc(sshUser): not contains(p, "/home/box") and not contains(p, "/home/ubuntu") for inherited base-home references covered by the generated rewrite block.
  • forall shell: nonInteractive(shell) -> source(zz-prompt.sh, shell) produces no prompt mutation and no TTY write.
  • forall r in cloneCacheRefreshRefs: r in refs/heads/* union refs/tags/*; in particular, refs/pull/* is excluded from cache refresh.
  • CORE -> SHELL boundary is preserved: this change modifies pure template rendering; runtime effects remain in generated shell scripts and Docker execution layers.

Preconditions

  • The selected DOCKER_GIT_BASE_IMAGE is Debian/Ubuntu-compatible and supports apt-based root setup.
  • The project container still runs docker-git's generated /entrypoint.sh.

Postconditions

  • Generated project containers inherit the shared link-foundation JS box runtime/tooling base.
  • docker-git-specific SSH/auth/bootstrap behavior remains rendered after the base image selection.
  • Non-interactive e2e commands can run under bash -lc without prompt/TTY side effects and with ~ and login rc paths resolving into the mounted SSH user home.
  • Reused clone-cache mirrors accelerate branch/tag object reuse without expanding the remote ref domain to every GitHub PR ref.

Complexity

  • Dockerfile and prompt rendering remain O(1) time and O(1) additional space.
  • Clone-cache refresh changes from O(|all remote refs|) to O(|heads| + |tags|) remote ref enumeration.

Verification

  • bun run --cwd packages/lib test -- tests/core/templates.test.ts
  • bun run check
  • bun run test
  • bun run build
  • bun run lint
  • bun run lint:effect
  • bun run check:dist-deps-prune
  • git diff --check

Note: this local runner does not have the docker binary installed, so local image build was not run here; Docker/E2E verification is covered by GitHub Actions on PR #281.

konard added 2 commits May 12, 2026 09:49
Adding .gitkeep for PR creation (default mode).
This file will be removed when the task is complete.

Issue: ProverCoderAI#267
@konard konard changed the title [WIP] Есть смысл юзать единные box контейнеры для работы feat(core): use shared box image for project containers May 12, 2026
@konard konard marked this pull request as ready for review May 12, 2026 10:17
@konard konard changed the title feat(core): use shared box image for project containers feat(core): use shared JS box image for project containers May 12, 2026
@konard
Copy link
Copy Markdown
Contributor Author

konard commented May 12, 2026

Working session summary

Done. PR #281 is updated and green: #281

Latest pushed head: bf18af78780766c71e0ded18b9305884305a66a1.

Key final fix:

  • Narrowed shared clone-cache mirror refresh from +refs/*:refs/* to heads/tags only in tasks.ts and the bundled app copy.
  • Added regression coverage in templates.test.ts to ensure refs/pull/* is not fetched during cache refresh.

Verification passed locally:
bun run check, bun run test, bun run build, bun run lint, bun run lint:effect, bun run check:dist-deps-prune, git diff --check.

GitHub checks passed on PR #281, including Docker E2E:
Clone cache, Login context, Runtime volumes + SSH, OpenCode, Browser command, and all static jobs.

Working tree is clean. SOURCE: n/a.


This summary was automatically extracted from the AI working session output.

@konard
Copy link
Copy Markdown
Contributor Author

konard commented May 12, 2026

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Model: GPT-5.5
  • Provider: OpenAI
  • Public pricing estimate: $88.495497

📊 Context and tokens usage:

  • 1.6M / 1.1M (149%) input tokens, 125.0K / 128K (98%) output tokens

Total: (1.6M + 67.2M cached) input tokens, 125.0K output tokens, $88.495497 cost

🤖 Models used:

  • Tool: OpenAI Codex
  • Requested: gpt-5.5
  • Model: GPT-5.5 (gpt-5.5)

📎 Log file uploaded as Repository (2 chunks) (201432KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard
Copy link
Copy Markdown
Contributor Author

konard commented May 12, 2026

✅ Ready to merge

This pull request is now ready to be merged:

  • All CI checks have passed
  • No merge conflicts
  • No pending changes

Monitored by hive-mind with --auto-restart-until-mergeable flag

@skulidropek
Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Параметризован базовый образ, нормализованы унаследованные пользователи/окружение, ужесточена логика промпта для интерактивных оболочек, добавлена валидация/парсер SSH-пользователя и shellSingleQuote, расширены шаблонные/entrypoint и конфигурационные тесты, обновлены e2e defaults, добавлен retry в Dockerfile и CI шаг очистки диска.

Изменения

Интеграция контейнеров Docker Box и улучшение скрипта приглашения

Layer / File(s) Summary
Параметризация базового образа и prelude
packages/lib/src/core/templates/dockerfile.ts, packages/app/src/lib/core/templates/dockerfile.ts
ARG DOCKER_GIT_BASE_IMAGE (по умолчанию konard/box-js:2.1.1) и FROM ${DOCKER_GIT_BASE_IMAGE}; USER root в преамбуле.
Bun профиль: сохранить runtime $PATH
packages/lib/src/core/templates/dockerfile.ts, packages/app/src/lib/core/templates/dockerfile.ts
renderDockerfileBunProfile экранирует $PATH как \$PATH, чтобы PATH расширялся в рантайме.
Нормализация пользователя и окружения образа
packages/lib/src/core/templates/dockerfile.ts, packages/app/src/lib/core/templates/dockerfile.ts
Retarget box/ubuntuconfig.sshUser, переписываются унаследованные rc/login файлы; устанавливаются ENV HOME, ENV PATH (включая .deno/.bun) и WORKDIR в /home/${config.sshUser}.
Workspace provisioning с безопасным chown
packages/lib/src/core/templates/dockerfile.ts, packages/app/src/lib/core/templates/dockerfile.ts
RUN-блок вычисляет HOME_DIR и TARGET_DIR, создаёт их, chown домашнего каталога и рекурсивный chown TARGET только когда он не / и не домашним каталогом.
Управление интерактивностью скрипта приглашения и обработка TTY
packages/lib/src/core/templates-prompt.ts, packages/app/src/lib/core/templates-prompt.ts
Переработка /dev/tty записей и stty sane с группированием перенаправлений; добавлен guard case "$-" для интерактивных оболочек; PROMPT_COMMAND цепочка проверяется через ${PROMPT_COMMAND-}.
SSH-валидаторы и парсеры
packages/lib/src/core/domain.ts, packages/app/src/lib/core/domain.ts, packages/lib/src/core/command-builders-shared.ts, packages/app/src/lib/core/command-builders-shared.ts, packages/lib/src/core/command-builders.ts, packages/app/src/lib/core/command-builders.ts
Добавлен unixUserNamePattern, sshUserNamePatternDescription, isUnixUserName и parseSshUser(...); call-sites обновлены для использования парсера; persisted ProjectConfig валидируется.
Shell quoting и entrypoint TARGET_DIR
packages/lib/src/core/shell-literals.ts, packages/app/src/lib/core/shell-literals.ts, packages/lib/src/core/templates-entrypoint/base.ts, packages/app/src/lib/core/templates-entrypoint/base.ts
Добавлен shellSingleQuote(value) и renderTargetDirDefault для безопасной установки TARGET_DIR только когда переменная пуста.
Парсеры CLI и тесты командных билдеров
packages/lib/tests/core/command-builders.test.ts, packages/app/tests/docker-git/parser.test.ts, packages/lib/src/core/command-builders-shared.ts, packages/app/src/docker-git/frontend-lib/core/command-builders-shared.ts
Добавлены JSDoc, экспорт parseSshUser, переключение вызова на parseSshUser и тесты (unit + property) для валидации/отклонения sshUser.
Тесты шаблонов и entrypoint
packages/lib/tests/core/templates.test.ts
Расширены проверки: base image, переименование пользователей, HOME/PATH/WORKDIR, escaped \$PATH, rc-файлы, targetDir quoting, chown поведение, renderPromptScript non-interactive guard, и clone-cache/refspec ограничения (heads/tags only).
readProjectConfig persisted sshUser проверки
packages/lib/tests/shell/config.test.ts
Добавлены helperы и property-тесты, которые записывают некорректные sshUser в docker-git.json и ожидают ConfigDecodeError с сообщением про шаблон имени пользователя.
apply usecase: Dockerfile assertion
packages/lib/tests/usecases/apply.test.ts
Ожидание TARGET_DIR='...' и mkdir -p "$HOME_DIR" "$TARGET_DIR" вместо прежнего одиночного mkdir.
API Dockerfile: retry установки зависимостей
packages/api/Dockerfile
bun install заменён на цикл 1–5 с логированием, очисткой cache/node_modules и экспоненциальным бэкоффом; ошибка после последней попытки.
e2e скрипты: defaults и diagnostics
scripts/e2e/opencode-autoconnect.sh, scripts/e2e/login-context.sh
ROOT_BASE по умолчанию /tmp/docker-git-e2e-root; on_error() печатает AUTH_LOG, если файл существует.
Apt invalid-signature detection and error hint
packages/app/src/lib/usecases/errors.ts, packages/lib/src/usecases/errors.ts, packages/lib/tests/usecases/errors.test.ts
Добавлен isAptInvalidSignatureFailure и подсказка о проверке диска и очистке Docker builder/image cache при соответствующих Docker build ошибках; тесты проверяют рендер hint.
GitHub action/workflow: free-docker-disk
.github/actions/free-docker-disk/action.yml, .github/workflows/check.yml
Добавлен composite action для освобождения места и вставлен в несколько E2E job-ов после установки зависимостей.
sequenceDiagram
  participant Shell as Shell (interactive?)
  participant PromptSanitizer as docker_git_terminal_sanitize
  participant TTY as /dev/tty
  participant PROMPT as PROMPT_COMMAND
  Shell->>PromptSanitizer: case "$-" check (interactive?)
  PromptSanitizer->>TTY: grouped printf write (escapes) with redirected stderr
  PromptSanitizer->>TTY: grouped stty sane fallback with redirected stderr
  PromptSanitizer->>PROMPT: append docker_git_prompt_apply using ${PROMPT_COMMAND-}
Loading

🎯 4 (Complex) | ⏱️ ~40 minutes

Возможно связанные PRы:

  • ProverCoderAI/docker-git#279: Пересечение по логике clone-cache/refspecs и тестам, ограничивающим fetch только heads/tags.

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Requirements Alignment ❌ Error PR claims to address CodeRabbit review threads but three suggested fixes remain unimplemented: apt predicate strictness, missing negative test, trailing slash vulnerability in chown. Apply the three CodeRabbit-suggested fixes: loosen apt predicate (remove apt-get update failed requirement), add negative regression test, normalize chown paths using ${VAR%/}.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Security Regression ❓ Inconclusive No result was produced after verification. Marking as INCONCLUSIVE. Re-run the check or adjust instructions to produce a final result.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Заголовок точно отражает главное изменение PR: переход на использование общего JS box образа для проектных контейнеров.
Description check ✅ Passed Описание полное и структурировано: содержит Summary, Reproduction, Changes, Mathematical Guarantees, Verification. Все требуемые разделы заполнены с достаточной детализацией.
Linked Issues check ✅ Passed PR полностью решает требования issue #267: внедрены переход на shared box образ, нормализация пользователей и окружения, сохранение docker-git функций, исключение PR-рефов из clone-cache.
Out of Scope Changes check ✅ Passed Все изменения соответствуют целям PR: модификации Dockerfile/prompt для box-совместимости, валидация sshUser, тесты регрессии, CI-действия для дискового пространства. Нет отклонений от scope.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot]
coderabbitai Bot previously requested changes May 13, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/lib/tests/core/templates.test.ts`:
- Around line 60-104: Add property-based tests (using fast-check) for the new
invariants around renderDockerfile outputs used in
packages/lib/tests/core/templates.test.ts (and the other ranges noted) instead
of only example-based assertions: write fast-check properties that call
renderDockerfile(makeTemplateConfig(arbitraryConfig)) to assert (1) refspec
exclusion invariant, (2) prompt non-interactive inertness invariant, and (3)
HOME/PATH/WORKDIR normalization invariant across generated configs (assert using
expect/contains helpers like expectContainsAll); use fast-check arbitraries for
TemplateConfig inputs, keep tests synchronous (no async/await), and put
unit-style checks using the project’s Effect test utilities where applicable
rather than raw async code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6bbab1ae-98b5-4847-a515-ad0643df2cd0

📥 Commits

Reviewing files that changed from the base of the PR and between 65c4f84 and 0ab5a45.

📒 Files selected for processing (7)
  • packages/app/src/lib/core/templates-entrypoint/tasks.ts
  • packages/app/src/lib/core/templates-prompt.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates-entrypoint/tasks.ts
  • packages/lib/src/core/templates-prompt.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts

Comment thread packages/lib/tests/core/templates.test.ts
@skulidropek skulidropek self-assigned this May 13, 2026
# Conflicts:
#	packages/app/src/lib/core/templates-entrypoint/tasks.ts
#	packages/lib/src/core/templates-entrypoint/tasks.ts
#	packages/lib/tests/core/templates.test.ts
@skulidropek
Copy link
Copy Markdown
Member

Merged current main into this PR and addressed the CodeRabbit review for property-based coverage.

Added fast-check invariants for:

  • clone-cache mirror refresh refspecs staying branch/tag-only;
  • prompt mutations remaining behind the non-interactive guard;
  • HOME/PATH/WORKDIR normalization across generated template configs.

Local verification:

  • bun run --cwd packages/lib test tests/core/templates.test.ts
  • bun run --cwd packages/lib typecheck
  • bun run --cwd packages/lib lint:effect

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
packages/lib/src/core/templates/dockerfile.ts (2)

17-53: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Добавьте исчерпывающую TSDoc для функции renderDockerfilePrelude.

Согласно гайдлайнам, все TypeScript-функции должны включать TSDoc с параметрами, типом возврата, маркерами @pure, @effect, @invariant, @precondition, @postcondition и @complexity в O-нотации. Функция renderDockerfilePrelude является чистой функцией CORE-слоя, генерирующей шаблон Dockerfile, и должна быть задокументирована.

📝 Предлагаемое дополнение TSDoc
+/**
+ * Renders the Dockerfile prelude with shared base image, root user context, and apt bootstrap setup.
+ *
+ * `@returns` Dockerfile prelude string with ARG/FROM/USER directives and apt package installation
+ * `@pure` true
+ * `@effect` none (CORE layer pure renderer)
+ * `@invariant` rendered output contains ARG DOCKER_GIT_BASE_IMAGE and FROM ${DOCKER_GIT_BASE_IMAGE}
+ * `@precondition` none
+ * `@postcondition` output is a valid Dockerfile prelude starting with ARG and FROM directives
+ * `@complexity` O(1) time / O(1) space
+ */
 const renderDockerfilePrelude = (): string =>

As per coding guidelines: **/*.{ts,tsx}: TypeScript functions must include comprehensive TSDoc with parameters, return types, @pure marker, @effect dependencies, @invariant (mathematical), @precondition, @postcondition, and @complexity O-notation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/src/core/templates/dockerfile.ts` around lines 17 - 53, Add a
comprehensive TSDoc block for the renderDockerfilePrelude function: document
that renderDockerfilePrelude is a pure, parameterless function in the CORE layer
that returns a string containing the Dockerfile prelude; include `@returns`
{string}, `@pure`, an `@effect` entry describing external effects/dependencies (none
or e.g., reads dockerGitBaseImage constant), an `@invariant` describing the
templated Dockerfile content contract, `@precondition` (none) and `@postcondition`
(returns a non-empty Dockerfile string), and a `@complexity` tag (O(1)); place the
TSDoc immediately above the renderDockerfilePrelude declaration and ensure
wording follows existing project TSDoc conventions.

220-271: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Добавьте исчерпывающую TSDoc для функции renderDockerfileUsers.

Хотя функция имеет отличные встроенные функциональные комментарии (CHANGE/WHY/INVARIANT/COMPLEXITY), согласно гайдлайнам требуется дополнительная TSDoc с полным набором аннотаций для TypeScript-функций.

📝 Предлагаемое дополнение TSDoc
+/**
+ * Renders Dockerfile RUN directives for SSH user setup with inherited base-image user migration.
+ *
+ * Renames box/ubuntu base users to config.sshUser, rewrites login rc files to normalize /home/box
+ * and /home/ubuntu references, sets ENV HOME/PATH/WORKDIR to /home/<sshUser>, and configures
+ * sshd hardening (password auth disabled, pubkey only, X11 forwarding enabled).
+ *
+ * `@param` config - Template configuration containing sshUser and other deployment settings
+ * `@returns` Dockerfile user setup block with migration, normalization, and sshd config
+ * `@pure` true
+ * `@effect` none (CORE layer pure renderer)
+ * `@invariant` forall u = config.sshUser: HOME = /home/u AND WORKDIR = /home/u AND login_rc files contain no /home/box or /home/ubuntu
+ * `@precondition` config.sshUser is a valid POSIX username (alphanumeric + underscore/dash)
+ * `@postcondition` rendered Dockerfile creates/migrates user with UID/GID 1000, normalizes paths, hardens sshd
+ * `@complexity` O(1) time / O(1) space (fixed number of RUN directives independent of config size)
+ */
 const renderDockerfileUsers = (config: TemplateConfig): string =>

As per coding guidelines: **/*.{ts,tsx}: TypeScript functions must include comprehensive TSDoc with parameters, return types, @pure marker, @effect dependencies, @invariant (mathematical), @precondition, @postcondition, and @complexity O-notation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/src/core/templates/dockerfile.ts` around lines 220 - 271, Add a
comprehensive TSDoc block immediately above the renderDockerfileUsers function
describing params and return and include the required annotations: `@param`
{TemplateConfig} config (documenting config.sshUser usage and expected
semantics), `@returns` {string}, `@pure`, `@effect` (list any external dependencies
like filesystem/OS semantics or shell command assumptions), `@invariant` (state
the HOME/tilde normalization invariant: HOME(rendered) = /home/u and login rc
files contain no "/home/box"), `@precondition` (e.g., config.sshUser non-empty and
valid username), `@postcondition` (e.g., generated Dockerfile ensures user exists
with UID/GID 1000 and HOME set to /home/${config.sshUser}), and `@complexity`
(O(1)/O(1)); ensure the doc mentions key symbols used in the function
(renderDockerfileUsers, TemplateConfig, config.sshUser) so reviewers can locate
the logic.
packages/app/src/lib/core/templates/dockerfile.ts (2)

220-271: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Добавьте исчерпывающую TSDoc для функции renderDockerfileUsers.

Хотя функция имеет отличные встроенные функциональные комментарии (CHANGE/WHY/INVARIANT/COMPLEXITY), согласно гайдлайнам требуется дополнительная TSDoc с полным набором аннотаций для TypeScript-функций.

📝 Предлагаемое дополнение TSDoc
+/**
+ * Renders Dockerfile RUN directives for SSH user setup with inherited base-image user migration.
+ *
+ * Renames box/ubuntu base users to config.sshUser, rewrites login rc files to normalize /home/box
+ * and /home/ubuntu references, sets ENV HOME/PATH/WORKDIR to /home/<sshUser>, and configures
+ * sshd hardening (password auth disabled, pubkey only, X11 forwarding enabled).
+ *
+ * `@param` config - Template configuration containing sshUser and other deployment settings
+ * `@returns` Dockerfile user setup block with migration, normalization, and sshd config
+ * `@pure` true
+ * `@effect` none (CORE layer pure renderer)
+ * `@invariant` forall u = config.sshUser: HOME = /home/u AND WORKDIR = /home/u AND login_rc files contain no /home/box or /home/ubuntu
+ * `@precondition` config.sshUser is a valid POSIX username (alphanumeric + underscore/dash)
+ * `@postcondition` rendered Dockerfile creates/migrates user with UID/GID 1000, normalizes paths, hardens sshd
+ * `@complexity` O(1) time / O(1) space (fixed number of RUN directives independent of config size)
+ */
 const renderDockerfileUsers = (config: TemplateConfig): string =>

As per coding guidelines: **/*.{ts,tsx}: TypeScript functions must include comprehensive TSDoc with parameters, return types, @pure marker, @effect dependencies, @invariant (mathematical), @precondition, @postcondition, and @complexity O-notation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/core/templates/dockerfile.ts` around lines 220 - 271,
Add a comprehensive TSDoc block above the renderDockerfileUsers function:
document the function description, param {TemplateConfig} config with details of
fields used (e.g., sshUser), return {string}, and include the required tags:
`@pure`, `@effect` (list side-effecting Dockerfile directives like user/group
modifications, sed rewrite, ENV/WORKDIR creation), `@invariant` (HOME(rendered) =
/home/u and no login rc contains "/home/box"), `@precondition` (config.sshUser is
a valid username), `@postcondition` (generated Dockerfile normalizes
HOME/PATH/WORKDIR and rewrites login files), and `@complexity` (time/space O(1));
reference the function name renderDockerfileUsers and the TemplateConfig type in
the doc so reviewers can locate the implementation.

17-53: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Добавьте исчерпывающую TSDoc для функции renderDockerfilePrelude.

Согласно гайдлайнам, все TypeScript-функции должны включать TSDoc с параметрами, типом возврата, маркерами @pure, @effect, @invariant, @precondition, @postcondition и @complexity в O-нотации. Функция renderDockerfilePrelude является чистой функцией CORE-слоя, генерирующей шаблон Dockerfile, и должна быть задокументирована.

📝 Предлагаемое дополнение TSDoc
+/**
+ * Renders the Dockerfile prelude with shared base image, root user context, and apt bootstrap setup.
+ *
+ * `@returns` Dockerfile prelude string with ARG/FROM/USER directives and apt package installation
+ * `@pure` true
+ * `@effect` none (CORE layer pure renderer)
+ * `@invariant` rendered output contains ARG DOCKER_GIT_BASE_IMAGE and FROM ${DOCKER_GIT_BASE_IMAGE}
+ * `@precondition` none
+ * `@postcondition` output is a valid Dockerfile prelude starting with ARG and FROM directives
+ * `@complexity` O(1) time / O(1) space
+ */
 const renderDockerfilePrelude = (): string =>

As per coding guidelines: **/*.{ts,tsx}: TypeScript functions must include comprehensive TSDoc with parameters, return types, @pure marker, @effect dependencies, @invariant (mathematical), @precondition, @postcondition, and @complexity O-notation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/core/templates/dockerfile.ts` around lines 17 - 53, The
function renderDockerfilePrelude is missing the required comprehensive TSDoc;
add a TSDoc block immediately above the renderDockerfilePrelude declaration that
describes its purpose (generates the Dockerfile prelude template), documents the
return type (`@returns` {string}), marks it `@pure`, lists `@effect` (e.g., reads
dockerGitBaseImage constant or "none" if no external effects), specifies an
`@invariant` (deterministic output for identical inputs), states `@precondition`
(none or any required env assumptions), states `@postcondition` (returns a
non-empty string that begins with "ARG DOCKER_GIT_BASE_IMAGE=" and contains
Ubuntu apt setup and sudoers entry), and annotates `@complexity` (O(1)); reference
the renderDockerfilePrelude symbol so reviewers can find the added TSDoc.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/lib/core/templates/dockerfile.ts`:
- Around line 203-205: Добавьте полную TSDoc над функцией
renderDockerfileBunProfile: опишите назначение функции (рендерит скрипт
/etc/profile.d/bun.sh с экранированным $PATH чтобы сохранить runtime-переменную,
а не подставлять её во время сборки), укажите возвращаемый тип string, пометьте
`@pure`, перечислите `@effect` зависимости (нет внешних эффектов, только
формирование строки), добавьте `@invariant` (результат всегда содержит "export
PATH=" и путь "/usr/local/bun/bin"), `@precondition` (функция не принимает
аргументов), `@postcondition` (возвращаемая строка заканчивается chmod 0644
/etc/profile.d/bun.sh), и `@complexity` O(1); поместите документацию прямо над
определением функции renderDockerfileBunProfile.

In `@packages/lib/src/core/templates/dockerfile.ts`:
- Around line 203-205: The function renderDockerfileBunProfile lacks the
required comprehensive TSDoc; add a full TSDoc block above
renderDockerfileBunProfile that explains the purpose (renders a /etc/profile.d
script that preserves the runtime $PATH by escaping $ at template time),
documents the return type (string), marks the function `@pure`, lists `@effect`
dependencies (none / no external state), states an `@invariant` (output always
contains an escaped "$PATH" and valid file path /etc/profile.d/bun.sh), includes
`@precondition` (no inputs required) and `@postcondition` (returned string is a
single RUN command writing and chmodding the file), and declares `@complexity`
O(1); reference the function name renderDockerfileBunProfile in the doc so
reviewers can locate it easily.

---

Outside diff comments:
In `@packages/app/src/lib/core/templates/dockerfile.ts`:
- Around line 220-271: Add a comprehensive TSDoc block above the
renderDockerfileUsers function: document the function description, param
{TemplateConfig} config with details of fields used (e.g., sshUser), return
{string}, and include the required tags: `@pure`, `@effect` (list side-effecting
Dockerfile directives like user/group modifications, sed rewrite, ENV/WORKDIR
creation), `@invariant` (HOME(rendered) = /home/u and no login rc contains
"/home/box"), `@precondition` (config.sshUser is a valid username), `@postcondition`
(generated Dockerfile normalizes HOME/PATH/WORKDIR and rewrites login files),
and `@complexity` (time/space O(1)); reference the function name
renderDockerfileUsers and the TemplateConfig type in the doc so reviewers can
locate the implementation.
- Around line 17-53: The function renderDockerfilePrelude is missing the
required comprehensive TSDoc; add a TSDoc block immediately above the
renderDockerfilePrelude declaration that describes its purpose (generates the
Dockerfile prelude template), documents the return type (`@returns` {string}),
marks it `@pure`, lists `@effect` (e.g., reads dockerGitBaseImage constant or "none"
if no external effects), specifies an `@invariant` (deterministic output for
identical inputs), states `@precondition` (none or any required env assumptions),
states `@postcondition` (returns a non-empty string that begins with "ARG
DOCKER_GIT_BASE_IMAGE=" and contains Ubuntu apt setup and sudoers entry), and
annotates `@complexity` (O(1)); reference the renderDockerfilePrelude symbol so
reviewers can find the added TSDoc.

In `@packages/lib/src/core/templates/dockerfile.ts`:
- Around line 17-53: Add a comprehensive TSDoc block for the
renderDockerfilePrelude function: document that renderDockerfilePrelude is a
pure, parameterless function in the CORE layer that returns a string containing
the Dockerfile prelude; include `@returns` {string}, `@pure`, an `@effect` entry
describing external effects/dependencies (none or e.g., reads dockerGitBaseImage
constant), an `@invariant` describing the templated Dockerfile content contract,
`@precondition` (none) and `@postcondition` (returns a non-empty Dockerfile string),
and a `@complexity` tag (O(1)); place the TSDoc immediately above the
renderDockerfilePrelude declaration and ensure wording follows existing project
TSDoc conventions.
- Around line 220-271: Add a comprehensive TSDoc block immediately above the
renderDockerfileUsers function describing params and return and include the
required annotations: `@param` {TemplateConfig} config (documenting config.sshUser
usage and expected semantics), `@returns` {string}, `@pure`, `@effect` (list any
external dependencies like filesystem/OS semantics or shell command
assumptions), `@invariant` (state the HOME/tilde normalization invariant:
HOME(rendered) = /home/u and login rc files contain no "/home/box"),
`@precondition` (e.g., config.sshUser non-empty and valid username),
`@postcondition` (e.g., generated Dockerfile ensures user exists with UID/GID 1000
and HOME set to /home/${config.sshUser}), and `@complexity` (O(1)/O(1)); ensure
the doc mentions key symbols used in the function (renderDockerfileUsers,
TemplateConfig, config.sshUser) so reviewers can locate the logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ce051469-fe1e-44b3-8376-9b3f8b000ecf

📥 Commits

Reviewing files that changed from the base of the PR and between 0ab5a45 and 5a2ceec.

📒 Files selected for processing (3)
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: Test
  • GitHub Check: E2E (Browser command)
  • GitHub Check: Lint
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: Final build (windows-latest)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/core/templates.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/core/templates.test.ts
🪛 Checkov (3.2.528)
packages/lib/src/core/templates/dockerfile.ts

[low] 19-19: Ensure the base image uses a non latest version tag

(CKV_DOCKER_7)


[low] 21-21: Ensure the last USER is not root

(CKV_DOCKER_8)

packages/app/src/lib/core/templates/dockerfile.ts

[low] 19-19: Ensure the base image uses a non latest version tag

(CKV_DOCKER_7)


[low] 21-21: Ensure the last USER is not root

(CKV_DOCKER_8)

🔇 Additional comments (4)
packages/lib/src/core/templates/dockerfile.ts (1)

6-15: LGTM!

packages/app/src/lib/core/templates/dockerfile.ts (1)

6-15: LGTM!

packages/lib/tests/core/templates.test.ts (2)

40-60: LGTM!

Also applies to: 112-131, 195-210, 225-241


177-211: Отличное использование Effect-TS для проверки поведения prompt-скрипта.

Тест корректно использует Effect.effect, Command, pipe и Effect.provide(NodeContext.layer) для выполнения bash-команды и проверки, что сгенерированный prompt-скрипт остаётся безмолвным в неинтерактивном режиме без TTY. Это соответствует гайдлайнам по использованию Effect-тестовых утилит вместо async/await.

Property-based проверка на строках 195-210 дополнительно верифицирует, что все интерактивные мутации (PROMPT_COMMAND, PS1, trap) расположены после non-interactive guard, что является математическим инвариантом.

As per coding guidelines: **/*.{test,spec}.{ts,tsx}: Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Comment thread packages/app/src/lib/core/templates/dockerfile.ts
Comment thread packages/lib/src/core/templates/dockerfile.ts
@skulidropek
Copy link
Copy Markdown
Member

Follow-up for CI: E2E (OpenCode) failed while running the pre-clone auth codex import/status block with its temp state under the repository .docker-git tree. I moved that e2e temp root to /tmp/docker-git-e2e-root, matching the other e2e scripts, so generated logs/auth fixtures are no longer part of the Docker controller build context.

Also added AUTH_LOG dumping on failure so future auth bootstrap errors are visible in Actions logs.

Local verification: bash -n scripts/e2e/opencode-autoconnect.sh and git diff --check.

@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 14, 2026

Pushed one more CI fix for the remaining red job.

What changed:

  • scripts/e2e/login-context.sh now uses /tmp/docker-git-e2e-root for its temporary E2E root by default, matching the OpenCode fix.
  • This keeps Login Context scratch state out of the repository checkout and avoids feeding transient E2E state into build/checkout disk pressure on GitHub runners.

Local verification:

  • bash -n scripts/e2e/login-context.sh
  • git diff --check

I also attempted the full Login Context e2e locally, but this container uses DOCKER_HOST=tcp://host.docker.internal:2375, and the docker-git host CLI refuses controller auto-discovery over remote DOCKER_HOST. The previous run showed OpenCode is green now; I am watching the new CI run for this head.

@skulidropek
Copy link
Copy Markdown
Member

Addressed the two unresolved CodeRabbit threads on the current review.

Changes:

  • Added TSDoc for renderDockerfileBunProfile in packages/app/src/lib/core/templates/dockerfile.ts.
  • Added the same TSDoc in packages/lib/src/core/templates/dockerfile.ts.

Local verification:

  • bun run --cwd packages/lib typecheck
  • bun run --cwd packages/app typecheck
  • git diff --check

Pushed as dd273e0.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/e2e/login-context.sh`:
- Line 8: Добавьте краткий inline-комментарий рядом с переменной ROOT_BASE (и
упоминанием DOCKER_GIT_E2E_ROOT_BASE) объясняющий, почему дефолтный путь выбран
как /tmp/docker-git-e2e-root (например: чтобы избежать repo-relative путей и
устранить E2E-падения в OpenCode), чтобы будущие разработчики видели контекст
изменения прямо в коде.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 043785b7-4791-4837-a304-14b1bf940a00

📥 Commits

Reviewing files that changed from the base of the PR and between 223ca99 and 25b7283.

📒 Files selected for processing (1)
  • scripts/e2e/login-context.sh
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: Test
  • GitHub Check: Lint
  • GitHub Check: Final build (windows-latest)
🧰 Additional context used
📓 Path-based instructions (1)
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • scripts/e2e/login-context.sh

Comment thread scripts/e2e/login-context.sh
@skulidropek
Copy link
Copy Markdown
Member

Pushed a fix for the new red E2E (Browser command) job.

Root cause from the job log:

  • the controller image build reached the Skiller submodule install step;
  • bun install --frozen-lockfile --silent failed with tarball integrity errors for @shikijs/themes and @mermaid-js/parser.

Change:

  • packages/api/Dockerfile now retries the Skiller submodule bun install up to 5 times, clearing /root/.bun/install/cache and node_modules between attempts. This mirrors the existing retry/cache-clear pattern already used for the top-level workspace install.

Local verification:

  • bun run --cwd packages/api build
  • git diff --check

Pushed as ba0a297.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/lib/core/templates/dockerfile.ts`:
- Around line 17-21: Добавьте полную TSDoc-комментарий над функцией
renderDockerfilePrelude: опишите параметры (их типы и предназначение), что
функция возвращает (строку Dockerfile-прелюдии), помяните новые поведения (ввод
ARG для базового образа, использование FROM с переменной и установку USER root),
и включите обязательные теги `@pure`, `@effect` (зависимости, если есть),
`@invariant`, `@precondition`, `@postcondition` и `@complexity` (о-большого O) в
соответствии с код-гайдлайном; используйте имя функции renderDockerfilePrelude в
комментарии, чтобы явно связать описание с реализацией.
- Around line 240-268: Добавьте формальную TSDoc над функцией
renderDockerfileUsers: опишите каждый параметр с `@param` (указать имя параметра и
тип/назначение), опишите возвращаемое значение с `@returns`, пометьте функцию как
`@pure`, перечислите внешние зависимости/побочные эффекты через `@effect`, укажите
инварианты через `@invariant`, предусловия через `@precondition` и постусловия через
`@postcondition`, а также оценку сложности через `@complexity` (Big-O). Убедитесь,
что теги соответствуют фактической сигнатуре и поведению renderDockerfileUsers
(включая имена параметров и типы), кратко и содержательно формулируйте каждое
условие и не дублируйте уже существующие комментарии.
- Around line 242-251: Здесь config.sshUser используется напрямую в
Dockerfile-шелл-командах (usermod -l ${config.sshUser}, groupmod -n
${config.sshUser}, useradd -g ${config.sshUser}, su - ${config.sshUser},
/etc/sudoers.d/${config.sshUser}) и отсутствует валидация в
TemplateConfigInputSchema; исправьте это добавлением pattern-валидации в
TemplateConfigInputSchema для поля sshUser с регулярным выражением
^[a-z_][a-z0-9_-]{0,31}$ (Unix username) либо — как
альтернативный/дополнительный защита — безопасно экранируйте/кавычьте при
интерполяции в шаблоне Dockerfile (использовать "${config.sshUser}" или
'${config.sshUser}') чтобы предотвратить возможность command injection.

In `@packages/lib/src/core/templates/dockerfile.ts`:
- Around line 240-266: Add a TSDoc block for the renderDockerfileUsers function
(which accepts a TemplateConfig) that documents the purpose, describes the
config parameter (TemplateConfig) and the returned string, and includes the
required tags: `@pure`, `@effect` (list any external deps, e.g., none or template
interpolation), `@invariant` (e.g., returns valid Dockerfile snippet),
`@precondition` (config has sshUser defined/non-empty), `@postcondition` (ENV and
WORKDIR set to /home/${config.sshUser}), and `@complexity` (O(1) or constant
time/space). Place the TSDoc immediately above the renderDockerfileUsers
declaration and ensure the descriptions are concise and accurate to satisfy the
linting rule.
- Around line 17-21: Добавьте полную TSDoc над функцией renderDockerfilePrelude:
опишите назначение функции, укажите возвращаемый тип (string), пометьте как
`@pure`, перечислите `@effect` зависимости (например переменная dockerGitBaseImage),
добавьте `@invariant` (что возвращаемая строка всегда содержит `FROM` и `USER
root`), `@precondition` (dockerGitBaseImage не пустой), `@postcondition` (результат
содержит ARG с заданным значением), и `@complexity` (O(1)); используйте краткие
разъяснения для параметризованного базового образа и верните документированный
блок над функцией renderDockerfilePrelude.
- Around line 242-248: Add POSIX username validation for config.sshUser and
ensure it's safely quoted in shell templates: update command-builders-shared.ts
to add a validator akin to parseSshPort that enforces the regex
^[a-z_][a-z0-9_-]*$ and wire it into TemplateConfigInputSchema (or validate via
an Either in resolveRepoBasics) so invalid sshUser values are rejected at
schema/resolve time; then update dockerfile.ts (places using config.sshUser in
commands like usermod -l ${config.sshUser}, groupmod -n ${config.sshUser}, and
any other shell interpolations) to emit the sshUser as a quoted/sanitized single
argument (e.g., wrap in single quotes or otherwise escape) so shell
metacharacters cannot cause injection or parsing errors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 746498d7-6785-4fca-afa6-79d92e66393d

📥 Commits

Reviewing files that changed from the base of the PR and between 25b7283 and dd273e0.

📒 Files selected for processing (2)
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
🔇 Additional comments (4)
packages/lib/src/core/templates/dockerfile.ts (2)

6-15: LGTM!


203-216: LGTM!

packages/app/src/lib/core/templates/dockerfile.ts (2)

203-216: LGTM!


264-266: LGTM!

Comment thread packages/app/src/lib/core/templates/dockerfile.ts
Comment thread packages/app/src/lib/core/templates/dockerfile.ts
Comment thread packages/app/src/lib/core/templates/dockerfile.ts Outdated
Comment thread packages/lib/src/core/templates/dockerfile.ts
Comment thread packages/lib/src/core/templates/dockerfile.ts
Comment thread packages/lib/src/core/templates/dockerfile.ts Outdated
@skulidropek
Copy link
Copy Markdown
Member

Addressed the latest CodeRabbit review notes in commit 6f23fe2.

What changed:

  • Added TSDoc for renderDockerfilePrelude and renderDockerfileUsers in both app/lib Dockerfile template copies.
  • Added the requested /tmp ROOT_BASE comment in scripts/e2e/login-context.sh.
  • Added a shared Linux sshUser invariant matching ^[a-z_][a-z0-9_-]{0,31}$ and wired it into create command builders across lib, app lib, and frontend-lib.
  • Added persisted docker-git.json validation so manually edited configs cannot bypass the sshUser invariant.
  • Added regression coverage for lib command building, config decode, template rendering, and the app CLI parser path.

Local verification passed:

  • bash -n scripts/e2e/login-context.sh
  • git diff --check and git diff --cached --check
  • bun run --cwd packages/lib test tests/core/command-builders.test.ts tests/shell/config.test.ts tests/core/templates.test.ts
  • bun run --cwd packages/lib typecheck
  • bun run --cwd packages/lib lint:effect
  • bun run --cwd packages/app typecheck
  • bun run --cwd packages/app test tests/docker-git/parser.test.ts

@skulidropek
Copy link
Copy Markdown
Member

Follow-up pushed in commit 8a99997 for the CI failure.

The failed E2E (Login context) log showed No space left on device while Docker was running chown -R 1000:1000 /home/dev. That recursively touched the inherited Playwright cache from the base image and inflated the layer.

Fix:

  • Do not recursively chown the whole inherited home directory during image build.
  • Chown the home directory itself non-recursively.
  • Recursively chown only the configured target workspace directory when it is not / and not the home directory.
  • Added a regression assertion in templates.test.ts so the full-home recursive chown does not come back.

Re-verified locally:

  • bun run --cwd packages/lib test tests/core/templates.test.ts tests/core/command-builders.test.ts tests/shell/config.test.ts
  • bun run --cwd packages/lib typecheck
  • bun run --cwd packages/lib lint:effect
  • bun run --cwd packages/app typecheck
  • bash -n scripts/e2e/login-context.sh
  • git diff --check

@skulidropek
Copy link
Copy Markdown
Member

Pushed commit 107800a for the failing Test job.

CI failure was an outdated assertion in packages/lib/tests/usecases/apply.test.ts that still expected the old exact Dockerfile line RUN mkdir -p . The Dockerfile now assigns TARGET_DIR and creates HOME_DIR/TARGET_DIR together to avoid recursive chown of the inherited home. The test now checks the new TARGET_DIR fragment instead.

Re-verified locally:

  • bun run --cwd packages/lib test tests/usecases/apply.test.ts tests/core/templates.test.ts tests/core/command-builders.test.ts tests/shell/config.test.ts
  • bun run --cwd packages/lib typecheck
  • bun run --cwd packages/lib lint:effect
  • bun run --cwd packages/app typecheck
  • git diff --check

@skulidropek
Copy link
Copy Markdown
Member

Final status for the latest head 107800a:

  • All GitHub checks are green, including Test and every E2E job.
  • The previous E2E (Login context) disk-space failure is fixed by avoiding recursive chown of the inherited home directory.
  • CodeRabbit status is SUCCESS.
  • I checked reviewThreads through gh api graphql: there are no unresolved review threads left.

Note: GitHub still reports reviewDecision as CHANGES_REQUESTED because CodeRabbit submitted an earlier CHANGES_REQUESTED review on 2026-05-13. The inline threads from that review are resolved, but the historical review state remains until the reviewer/bot updates or a maintainer dismisses it.

@skulidropek
Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/lib/src/core/command-builders-shared.ts`:
- Around line 34-52: Add a complete TSDoc contract to every public parser in
this file (at least parseSshUser, parseSshPort, parseDockerNetworkMode,
parseGpuMode, and nonEmpty): for each function add a summary, `@param` describing
the input, `@returns` describing the Either result, and include the required
annotation tags `@pure`, `@effect`, `@invariant`, `@precondition`, `@postcondition`, and
`@complexity` with concise, accurate statements about side effects (none),
expected input constraints, guaranteed outputs (left on error, right on valid
value), and time/space complexity; ensure the TSDoc sits immediately above each
function declaration (e.g., above parseSshUser) and uses precise wording
reflecting the actual validation rules (e.g., username pattern, non-empty),
matching the function behavior.

In `@packages/lib/src/core/templates/dockerfile.ts`:
- Around line 329-334: The Dockerfile template injects config.targetDir raw into
the RUN shell, allowing shell metacharacters (e.g., $(), backticks) to be
executed; before emitting TARGET_DIR="${config.targetDir}" escape the value for
safe single-quoted shell usage (e.g., replace every single quote with '\'' and
wrap the whole value in single quotes) so the generated line becomes
TARGET_DIR='escaped-value' and not subject to shell expansion, update the code
that renders TARGET_DIR in the dockerfile template (the place that references
config.targetDir and the RUN block containing TARGET_DIR/HOME_DIR/chown) and
apply the same escaping fix to the other dockerfile template used for the app.

In `@packages/lib/tests/core/command-builders.test.ts`:
- Around line 7-33: Add property-based tests for the sshUser invariant by using
fast-check to generate many valid and invalid usernames and asserting
buildCreateCommand(...) respects the regex; specifically, write
fc.assert(fc.property(...)) cases that feed generated strings into
buildCreateCommand (referencing the function buildCreateCommand and the sshUser
property) and assert Either.isRight for strings matching
^[a-z_][a-z0-9_-]{0,31}$ (and that result.right.config.sshUser equals the input)
and Either.isLeft with the InvalidOption shape (option: "--ssh-user", reason
matching the regex message) for non-matching strings (edge lengths 0,32,33,
invalid first char, forbidden chars); use fast-check generators (e.g., custom
char/length constraints) and fc.assert/fc.property directly (no async/await) to
follow the test conventions.

In `@packages/lib/tests/shell/config.test.ts`:
- Around line 40-61: Добавьте property-based тест с fast-check that проверяет
инвариант валидации sshUser: вместо одного примера, сгенерируйте множество
невалидных юзернеймов (строки, содержащие shell-метасимволы, заглавные буквы,
длину >31 и т.п.) и для каждого записывайте config (используя
makeTemplateConfig) в tempDir и вызывайте readProjectConfig(tempDir); ожидайте
Left/ConfigDecodeError и сообщение содержит "template.sshUser must match".
Импортируйте fast-check (fc), используйте fc.property / fc.assert с подходящими
генераторами (или комбинируйте fc.oneof/filters для спецсимволов, uppercase,
слишком длинных строк), и ссыльтесь в тесте на isUnixUserName semantics by
asserting that all generated unsafe values are rejected by readProjectConfig /
the decoder.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 32d8f521-cffd-477d-908f-0fb3c7172a75

📥 Commits

Reviewing files that changed from the base of the PR and between dd273e0 and 107800a.

📒 Files selected for processing (20)
  • packages/api/Dockerfile
  • packages/app/src/docker-git/frontend-lib/core/command-builders-shared.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders.ts
  • packages/app/src/docker-git/frontend-lib/core/domain.ts
  • packages/app/src/lib/core/command-builders-shared.ts
  • packages/app/src/lib/core/command-builders.ts
  • packages/app/src/lib/core/domain.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/lib/shell/config.ts
  • packages/app/tests/docker-git/parser.test.ts
  • packages/lib/src/core/command-builders-shared.ts
  • packages/lib/src/core/command-builders.ts
  • packages/lib/src/core/domain.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/shell/config.ts
  • packages/lib/tests/core/command-builders.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/shell/config.test.ts
  • packages/lib/tests/usecases/apply.test.ts
  • scripts/e2e/login-context.sh
📜 Review details
🧰 Additional context used
📓 Path-based instructions (5)
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • scripts/e2e/login-context.sh
  • packages/api/Dockerfile
  • packages/lib/src/core/command-builders-shared.ts
  • packages/app/src/lib/core/domain.ts
  • packages/lib/tests/core/command-builders.test.ts
  • packages/app/src/lib/shell/config.ts
  • packages/lib/tests/usecases/apply.test.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders.ts
  • packages/app/tests/docker-git/parser.test.ts
  • packages/lib/src/core/command-builders.ts
  • packages/app/src/docker-git/frontend-lib/core/domain.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders-shared.ts
  • packages/lib/tests/shell/config.test.ts
  • packages/lib/src/shell/config.ts
  • packages/app/src/lib/core/command-builders-shared.ts
  • packages/app/src/lib/core/command-builders.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/domain.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates/dockerfile.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/lib/src/core/command-builders-shared.ts
  • packages/app/src/lib/core/domain.ts
  • packages/lib/tests/core/command-builders.test.ts
  • packages/app/src/lib/shell/config.ts
  • packages/lib/tests/usecases/apply.test.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders.ts
  • packages/app/tests/docker-git/parser.test.ts
  • packages/lib/src/core/command-builders.ts
  • packages/app/src/docker-git/frontend-lib/core/domain.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders-shared.ts
  • packages/lib/tests/shell/config.test.ts
  • packages/lib/src/shell/config.ts
  • packages/app/src/lib/core/command-builders-shared.ts
  • packages/app/src/lib/core/command-builders.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/domain.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates/dockerfile.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/lib/src/core/command-builders-shared.ts
  • packages/app/src/lib/core/domain.ts
  • packages/lib/tests/core/command-builders.test.ts
  • packages/app/src/lib/shell/config.ts
  • packages/lib/tests/usecases/apply.test.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders.ts
  • packages/app/tests/docker-git/parser.test.ts
  • packages/lib/src/core/command-builders.ts
  • packages/app/src/docker-git/frontend-lib/core/domain.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders-shared.ts
  • packages/lib/tests/shell/config.test.ts
  • packages/lib/src/shell/config.ts
  • packages/app/src/lib/core/command-builders-shared.ts
  • packages/app/src/lib/core/command-builders.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/domain.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/src/core/templates/dockerfile.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/core/command-builders.test.ts
  • packages/lib/tests/usecases/apply.test.ts
  • packages/app/tests/docker-git/parser.test.ts
  • packages/lib/tests/shell/config.test.ts
  • packages/lib/tests/core/templates.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/core/command-builders.test.ts
  • packages/lib/tests/usecases/apply.test.ts
  • packages/app/tests/docker-git/parser.test.ts
  • packages/lib/tests/shell/config.test.ts
  • packages/lib/tests/core/templates.test.ts
🪛 Checkov (3.2.528)
packages/app/src/lib/core/templates/dockerfile.ts

[low] 28-28: Ensure the base image uses a non latest version tag

(CKV_DOCKER_7)


[low] 30-30: Ensure the last USER is not root

(CKV_DOCKER_8)

packages/lib/src/core/templates/dockerfile.ts

[low] 28-28: Ensure the base image uses a non latest version tag

(CKV_DOCKER_7)


[low] 30-30: Ensure the last USER is not root

(CKV_DOCKER_8)

🔇 Additional comments (12)
scripts/e2e/login-context.sh (1)

8-10: LGTM!

packages/api/Dockerfile (1)

77-88: LGTM!

packages/app/src/docker-git/frontend-lib/core/domain.ts (1)

61-75: LGTM!

packages/app/src/lib/core/domain.ts (1)

61-75: LGTM!

packages/lib/src/core/domain.ts (1)

60-74: LGTM!

packages/app/src/lib/core/command-builders-shared.ts (1)

4-12: LGTM!

Also applies to: 35-53

packages/app/src/docker-git/frontend-lib/core/command-builders-shared.ts (1)

4-12: LGTM!

Also applies to: 35-53

packages/app/src/docker-git/frontend-lib/core/command-builders.ts (1)

6-6: LGTM!

Also applies to: 49-49

packages/app/src/lib/shell/config.ts (1)

10-15: LGTM!

Also applies to: 94-106, 126-126

packages/app/src/lib/core/command-builders.ts (1)

6-6: LGTM!

Also applies to: 49-49

packages/lib/tests/shell/config.test.ts (1)

1-37: LGTM!

Also applies to: 62-64

packages/lib/src/core/command-builders-shared.ts (1)

3-11: LGTM!

Comment thread packages/lib/src/core/command-builders-shared.ts
Comment thread packages/lib/tests/core/command-builders.test.ts
Comment thread packages/lib/tests/shell/config.test.ts
@skulidropek
Copy link
Copy Markdown
Member

Updated PR #281 for the latest CodeRabbit review (#4289505285).

What changed:

  • Added full parser TSDoc contracts for the public parser functions and mirrored the bundled app/frontend-lib copies.
  • Added a shared POSIX shell literal helper and used it for generated Dockerfile and entrypoint TARGET_DIR defaults, so command substitutions remain data.
  • Added fast-check coverage for valid/invalid sshUser parsing, boundary lengths, and persisted docker-git.json config decode failures.
  • Pinned the shared Box JS base image default to konard/box-js:2.1.1 instead of latest.
  • Kept USER root intentionally for the docker-git entrypoint/sshd/auth/bootstrap precondition, with a Checkov CKV_DOCKER_8 skip reason instead of changing runtime semantics.

Local verification passed:

  • bun run --cwd packages/lib test -- tests/shell/config.test.ts tests/core/command-builders.test.ts tests/core/templates.test.ts tests/usecases/apply.test.ts
  • bun run check
  • bun run lint:effect
  • bun run lint
  • bun run test
  • bun run build
  • git diff --check

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

@skulidropek Thanks for the detailed update! The changes look well-considered — particularly pinning to konard/box-js:2.1.1 instead of latest for reproducibility, adding the Checkov skip annotation for USER root with a clear rationale, and the POSIX shell literal helper for safe TARGET_DIR defaults. I'll review the latest commits now.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/lib/tests/core/templates.test.ts`:
- Around line 159-160: Ассерт в тесте использует обычную строку с литералом
"${config.sshUser}" вместо подстановки значения, поэтому реальный путь не
проверяется; в выражении expect(dockerfile).not.toContain("chown -R 1000:1000
/home/${config.sshUser}") замените строку на интерполируемую (например,
использовать шаблонную строку с backticks) или конкатенацию со значением
config.sshUser так, чтобы проверка реально искала "chown -R 1000:1000
/home/<значение>".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 31f8aea1-ac14-4900-af6f-5bb1757163f8

📥 Commits

Reviewing files that changed from the base of the PR and between 107800a and c537c64.

📒 Files selected for processing (16)
  • packages/app/src/docker-git/frontend-lib/core/command-builders-shared.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders.ts
  • packages/app/src/lib/core/command-builders-shared.ts
  • packages/app/src/lib/core/command-builders.ts
  • packages/app/src/lib/core/shell-literals.ts
  • packages/app/src/lib/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/command-builders-shared.ts
  • packages/lib/src/core/command-builders.ts
  • packages/lib/src/core/shell-literals.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/command-builders.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/shell/config.test.ts
  • packages/lib/tests/usecases/apply.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone auto-open SSH)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/lib/tests/usecases/apply.test.ts
  • packages/app/src/lib/core/shell-literals.ts
  • packages/lib/src/core/shell-literals.ts
  • packages/app/src/lib/core/command-builders.ts
  • packages/lib/src/core/command-builders.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/tests/core/command-builders.test.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders.ts
  • packages/lib/tests/shell/config.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/command-builders-shared.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders-shared.ts
  • packages/lib/src/core/command-builders-shared.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/usecases/apply.test.ts
  • packages/lib/tests/core/command-builders.test.ts
  • packages/lib/tests/shell/config.test.ts
  • packages/lib/tests/core/templates.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/lib/tests/usecases/apply.test.ts
  • packages/app/src/lib/core/shell-literals.ts
  • packages/lib/src/core/shell-literals.ts
  • packages/app/src/lib/core/command-builders.ts
  • packages/lib/src/core/command-builders.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/tests/core/command-builders.test.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders.ts
  • packages/lib/tests/shell/config.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/command-builders-shared.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders-shared.ts
  • packages/lib/src/core/command-builders-shared.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/usecases/apply.test.ts
  • packages/lib/tests/core/command-builders.test.ts
  • packages/lib/tests/shell/config.test.ts
  • packages/lib/tests/core/templates.test.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/lib/tests/usecases/apply.test.ts
  • packages/app/src/lib/core/shell-literals.ts
  • packages/lib/src/core/shell-literals.ts
  • packages/app/src/lib/core/command-builders.ts
  • packages/lib/src/core/command-builders.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/tests/core/command-builders.test.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders.ts
  • packages/lib/tests/shell/config.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/command-builders-shared.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders-shared.ts
  • packages/lib/src/core/command-builders-shared.ts
🪛 Checkov (3.2.528)
packages/app/src/lib/core/templates/dockerfile.ts

[low] 31-31: Ensure the base image uses a non latest version tag

(CKV_DOCKER_7)

packages/lib/src/core/templates/dockerfile.ts

[low] 31-31: Ensure the base image uses a non latest version tag

(CKV_DOCKER_7)

🔇 Additional comments (16)
packages/app/src/docker-git/frontend-lib/core/command-builders-shared.ts (1)

4-12: LGTM!

Also applies to: 33-44, 47-77, 79-90, 105-116, 131-144

packages/app/src/docker-git/frontend-lib/core/command-builders.ts (1)

6-12: LGTM!

Also applies to: 55-55

packages/app/src/lib/core/command-builders-shared.ts (1)

4-12: LGTM!

Also applies to: 33-45, 47-77, 79-90, 105-116, 131-144

packages/app/src/lib/core/command-builders.ts (1)

6-12: LGTM!

Also applies to: 55-55

packages/lib/src/core/command-builders-shared.ts (1)

3-11: LGTM!

Also applies to: 32-44, 46-76, 78-89, 104-115, 130-143

packages/lib/src/core/command-builders.ts (1)

6-12: LGTM!

Also applies to: 55-55

packages/lib/tests/core/command-builders.test.ts (1)

1-145: LGTM!

packages/lib/tests/shell/config.test.ts (1)

1-127: LGTM!

packages/lib/src/core/shell-literals.ts (1)

1-22: LGTM!

packages/app/src/lib/core/shell-literals.ts (1)

1-22: LGTM!

packages/app/src/lib/core/templates-entrypoint/base.ts (1)

2-10: LGTM!

Also applies to: 18-18

packages/lib/src/core/templates-entrypoint/base.ts (1)

2-10: LGTM!

Also applies to: 18-18

packages/lib/src/core/templates/dockerfile.ts (1)

2-2: LGTM!

Also applies to: 7-17, 18-34, 216-229, 244-307, 332-356

packages/app/src/lib/core/templates/dockerfile.ts (1)

2-2: LGTM!

Also applies to: 7-17, 18-34, 216-229, 244-307, 332-356

packages/lib/tests/usecases/apply.test.ts (1)

194-195: LGTM!

packages/lib/tests/core/templates.test.ts (1)

1-158: LGTM!

Also applies to: 162-653

Comment thread packages/lib/tests/core/templates.test.ts Outdated
@skulidropek
Copy link
Copy Markdown
Member

Follow-up CI fix after the new head c537c64:

E2E (Clone cache) failed while exporting the built Docker image with no space left on device on the GitHub-hosted runner. The runtime checks before that were passing; this is disk pressure from the larger shared Box base image, not a clone-cache assertion failure.

Pushed ffa9f80:

  • adds .github/actions/free-docker-disk to remove unused hosted-runner toolchains and prune Docker storage;
  • runs it before all Docker E2E jobs so the Box-based image builds have enough space.

Validation before push:

  • previous local checks remained green (bun run check, bun run lint, bun run test, bun run build, git diff --check);
  • workflow YAML/action diff is CI-only and git diff --check passed.

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

@skulidropek Thanks for the follow-up fix! The approach of proactively freeing disk space on the GitHub-hosted runner before Docker E2E jobs is a well-established pattern for handling larger base images — removing unused toolchains (e.g., Android SDK, .NET, Haskell) and pruning stale Docker storage typically recovers 20–40 GB on standard ubuntu-latest runners, which should give the konard/box-js:2.1.1-based builds plenty of headroom.

I'll review the latest commits now, including the new .github/actions/free-docker-disk composite action.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@skulidropek skulidropek dismissed coderabbitai[bot]’s stale review May 14, 2026 12:47

Stale CodeRabbit change request from 0ab5a45. All review threads are resolved, latest head 578de65 is green, and CodeRabbit completed the latest review without new actionable comments.

@skulidropek
Copy link
Copy Markdown
Member

Final status on PR #281 after latest fixes:

  • Head: 578de65
  • CI: all 19 checks passing, including all Docker E2E jobs.
  • CodeRabbit: latest review completed; no new actionable comments after the addressed test assertion.
  • Review threads: 0 unresolved.
  • Stale CodeRabbit CHANGES_REQUESTED from an old commit was dismissed after the latest green review/checks.

The Box-container migration checks are green now.

@skulidropek
Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/lib/core/templates/dockerfile.ts`:
- Around line 336-341: The string comparison between TARGET_DIR and HOME_DIR can
be fooled by trailing slashes (e.g. "/home/user/" vs "/home/user"); normalize
both variables before the conditional chown to ensure exact path equality.
Update the RUN block handling TARGET_DIR and HOME_DIR so you strip any trailing
slashes (e.g., using shell parameter expansion like ${VAR%/}) for both HOME_DIR
and TARGET_DIR before the if test, then keep the existing conditional chown -R
1000:1000 "$TARGET_DIR" only when the normalized TARGET_DIR is neither "/" nor
equal to the normalized HOME_DIR.

In `@packages/app/src/lib/usecases/errors.ts`:
- Around line 92-98: The predicate in isAptInvalidSignatureFailure is too strict
because it requires the exact phrase "apt-get update failed"; relax it by
removing that requirement and instead return true when the normalized details
(from parameter details assigned to variable normalized) contains "invalid
signature" and "repository" and "not signed" (optionally also allow the broader
token "apt" or "apt-get" if you want to keep an explicit apt-related guard).
Update the function isAptInvalidSignatureFailure to use only the looser checks
on normalized so cases missing the exact "apt-get update failed" phrase still
match.

In `@packages/lib/src/core/templates/dockerfile.ts`:
- Around line 336-341: Строковое сравнение TARGET_DIR и $HOME_DIR допускает
различие только из‑за trailing slash, поэтому нормализуйте путь TARGET_DIR
(убрать завершающий слеш и, опционально, привести к каноничному виду) перед
проверки в условии в шаблоне (в блоке где задаются
TARGET_DIR=${targetDirLiteral} и проверяется if [ "$TARGET_DIR" != "/" ] && [
"$TARGET_DIR" != "$HOME_DIR" ]; then chown -R 1000:1000 "$TARGET_DIR"; fi),
чтобы эквивалентные пути типа /home/${config.sshUser} и /home/${config.sshUser}/
считались одинаковыми; обновите условие использовать нормализованный TARGET_DIR
или сравнение без trailing slash и добавьте регрессионный тест на случай
targetDir с завершающим слешем.

In `@packages/lib/tests/usecases/errors.test.ts`:
- Around line 45-62: Add a negative regression test in the same test suite
(packages/lib/tests/usecases/errors.test.ts) that constructs a
DockerCommandError and calls renderError but omits the full combination of apt
failure signatures (e.g., include only "W: GPG error..." or only "E: The
repository ... is not signed." but not both) and assert that the returned
message does NOT contain the disk-pressure hints ("low Docker host disk space",
"df -h", "docker builder prune -af", "docker image prune -af"); use a
descriptive it() name like "does not include disk pressure recovery hint when
apt signature pattern is incomplete" and reuse the existing helpers/constructors
renderError and DockerCommandError to keep the test consistent with the positive
case.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 72fc4062-2923-45c9-8379-754f846c8db1

📥 Commits

Reviewing files that changed from the base of the PR and between ffa9f80 and 5c2656b.

📒 Files selected for processing (6)
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/lib/usecases/errors.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/errors.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/errors.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/lib/tests/usecases/errors.test.ts
  • packages/app/src/lib/usecases/errors.ts
  • packages/lib/src/usecases/errors.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/usecases/errors.test.ts
  • packages/lib/tests/core/templates.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/lib/tests/usecases/errors.test.ts
  • packages/app/src/lib/usecases/errors.ts
  • packages/lib/src/usecases/errors.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/usecases/errors.test.ts
  • packages/lib/tests/core/templates.test.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/lib/tests/usecases/errors.test.ts
  • packages/app/src/lib/usecases/errors.ts
  • packages/lib/src/usecases/errors.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/lib/tests/usecases/errors.test.ts
  • packages/app/src/lib/usecases/errors.ts
  • packages/lib/src/usecases/errors.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/lib/tests/usecases/errors.test.ts
  • packages/app/src/lib/usecases/errors.ts
  • packages/lib/src/usecases/errors.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/lib/tests/usecases/errors.test.ts
  • packages/app/src/lib/usecases/errors.ts
  • packages/lib/src/usecases/errors.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
🪛 Checkov (3.2.528)
packages/lib/src/core/templates/dockerfile.ts

[low] 31-31: Ensure the base image uses a non latest version tag

(CKV_DOCKER_7)

packages/app/src/lib/core/templates/dockerfile.ts

[low] 31-31: Ensure the base image uses a non latest version tag

(CKV_DOCKER_7)

🔇 Additional comments (1)
packages/lib/src/usecases/errors.ts (1)

91-97: Дубликат: тот же риск переузкой классификации apt-сбоя, что и в app-версии.

Примените то же исправление и здесь, чтобы поведение packages/app и packages/lib не расходилось.

Comment thread packages/app/src/lib/core/templates/dockerfile.ts Outdated
Comment thread packages/app/src/lib/usecases/errors.ts
Comment thread packages/lib/src/core/templates/dockerfile.ts Outdated
Comment thread packages/lib/tests/usecases/errors.test.ts
@skulidropek skulidropek merged commit 6354bd0 into ProverCoderAI:main May 14, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Есть смысл юзать единные box контейнеры для работы

2 participants